#include "cyclequeue.h"



// cycle queue init 
void CQueueInit(PCQNode cqueue)
{
	assert(cqueue);
	//malloc memory space
	CQDataType* newdata = (CQDataType*)malloc(MAX_QNODE*sizeof(CQDataType));
	if (!newdata)
	{
		perror("CQueueInit::malloc::");
		return;
	}
	//init cycle queue struct member
	cqueue->pdata = newdata;
	cqueue->headindex = 0;
	cqueue->tailindex = 0;
	cqueue->maxdata = MAX_QNODE;
	cqueue->validdata = 0;
}

// cycle queue destroy
void CQueueDestroy(PCQNode cqueue)
{
	assert(cqueue);
	//free cycle queue member data pointer
	free(cqueue->pdata);
	cqueue->pdata = NULL;
	//init cycle queue struct member
	cqueue->headindex = 0;
	cqueue->tailindex = 0;
	cqueue->maxdata = MAX_QNODE;
	cqueue->validdata = 0;
}


// cycle queue push
void CQueuePush(PCQNode cqueue, CQDataType value)
{
	assert(cqueue);
	//queue memory space is full
	if (cqueue->validdata == cqueue->maxdata)
	{
		printf("CQueuePush::queue memory space is full\n");
		return;
	}
	//push value
	cqueue->pdata[cqueue->tailindex] = value;

	//print pop data
	printf("push::%d\n", cqueue->pdata[cqueue->tailindex]);


	//tail index add one; valid add one
	cqueue->tailindex++;
	cqueue->validdata++;
	//if tail index equal to cycle queue max data, tail index equal to zero
	if (cqueue->tailindex >= cqueue->maxdata)
	{
		cqueue->tailindex = 0;
	}
}

// cycle queue pop
void CQueuePop(PCQNode cqueue)
{
	assert(cqueue);
	//queue memory space is empty
	if (cqueue->validdata == 0)
	{
		printf("CQueuePush::queue memory space is empty\n");
		return;
	}

	//print pop data
	printf("pop::%d\n", cqueue->pdata[cqueue->headindex]);

	//head index add one; valid sub one
	cqueue->headindex++;
	cqueue->validdata--;
	//if tail index equal to cycle queue max data, tail index equal to zero
	if (cqueue->headindex >= cqueue->maxdata)
	{
		cqueue->headindex = 0;
	}
}


// return cycle queue front
CQDataType CQueueFront(PCQNode cqueue)
{
	assert(cqueue);
	//queue memory space is empty
	if (cqueue->validdata == 0)
	{
		printf("CQueuePush::queue memory space is empty\n");
		return -1;
	}
	//return cycle queue head index data
	return (cqueue->pdata[cqueue->headindex]);
}

// return cycle queue back
CQDataType CQueueBack(PCQNode cqueue)
{
	assert(cqueue);
	//queue memory space is empty
	if (cqueue->validdata == 0)
	{
		printf("CQueuePush::queue memory space is empty\n");
		return -1;
	}
	//if tail index equal to zero,
	if (cqueue->tailindex == 0)
	{
		//return cycle queue max sub one data
		return (cqueue->pdata[(cqueue->maxdata)-1]);
	}
	else
	{
		//return cycle queue tail index sub one data
		return (cqueue->pdata[(cqueue->tailindex) - 1]);
	}
}


// return cycle queue empty
//if queue is empty, bool equal to true
//else, bool equal to false
bool CQueueEmpty(PCQNode cqueue)
{
	assert(cqueue);
	//valid data is zero
	if (cqueue->validdata == 0)
		return true;
	else
		return false;
}

// return cycle queue full
//if queue is full, bool==true
//else, bool==false
bool CQueueFull(PCQNode cqueue)
{
	assert(cqueue);
	//valid data is full
	if (cqueue->validdata == cqueue->maxdata)
		return true;
	else
		return false;
}


// return cycle queue max data size
int CQueueSize(PCQNode cqueue)
{
	assert(cqueue);
	//return cycle queue max data size
	return (cqueue->maxdata);
}

// return cycle queue valid data size
int CQueueValid(PCQNode cqueue)
{
	assert(cqueue);
	//return cycle queue valid data size
	return (cqueue->validdata);
}





